#安装项目

#在CMakeList中编写安装项目的相关代码。把生成的库和相关的头文件，安装到对应的系统目录下，去供别人使用。

cmake_minimum_required(VERSION 3.10)
project(course_05)

set(CMAKE_CXX_STANDARD 11)  # 将 C++ 标准设置为 C++ 11
set(CMAKE_CXX_STANDARD_REQUIRED ON)  # C++ 11 是强制要求，不会衰退至低版本
set(CMAKE_CXX_EXTENSIONS OFF)  # 禁止使用编译器特有扩展

if(NOT CMAKE_BUILD_TYPE)
    message(WARNING "NOT SET CMAKE_BUILD_TYPE")
    set(CMAKE_BUILD_TYPE "Release")
endif()

#使用aux_source_directory获取所有源文件,src 目录
aux_source_directory(src SRC)
message("SRC内容是->${SRC}" )#SRC内容 src/add.cpp;src/main.cpp;src/sub.cpp
#设置头文件路径
set(INCLUDE "include")

add_library(my_math)
target_sources(my_math PRIVATE ${SRC}) #设置源文件

target_include_directories(my_math PUBLIC ${INCLUDE}) #设置头文件

add_executable(run test/main.cpp)
target_link_libraries(run my_math)

#CMAKE_INSTALL_PREFIX 设置CMAKE构建过程中的安装路径，默认为 /usr/local
set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/install/)

#安装run和my_math两个目标
install(TARGETS 
            run my_math
            RUNTIME DESTINATION bin  #RUNTIME表示可执行文件被安装到bin目录下
            LIBRARY DESTINATION lib) #LIBRARY表示静态库会被安装在lib下
                                     #这里的目标都是相对路径，相对于 CMAKE_INSTALL_PREFIX

#安装头文件
install(FILES 
                include/my_math.hpp DESTINATION my_math/include)# 将my_math.hpp安装到${CMAKE_INSTALL_PREFIX}/my_math/include

#命令行使用下列命令，进行安装步骤
#cmake --install /root/Learn/cmakeStudy/build --prefix /root/Learn/cmakeStudy/install

#[[

target_include_directories(my_math PUBLIC ${INCLUDE}) #设置头文件

PRIVATE 用于库的内部使用，例如 my_math 库编译时，add.cpp 和 sub.cpp 会使用 include 路径，但外部不会知道或依赖这个路径。
INTERFACE 用于库外部使用，假设其他目标（如 main.cpp）链接了 my_math 库，链接时需要使用该库的头文件路径。main.cpp 不需要自己设置路径，而是通过 target_link_libraries 获得。
PUBLIC 则是 PRIVATE 和 INTERFACE 的组合，既适用于库的内部，也会对外部目标暴露路径。例如，main.cpp 在链接 my_math 后，能够自动找到 my_math 库的头文件路径。
总结：
PRIVATE：库的内部路径，其他目标无关。
INTERFACE：其他目标使用的路径，库自身不依赖。
PUBLIC：对内外都有效的路径，既包括库的内部，也包括链接该库的目标

从本质上来看target_include_directories总归是为目标的属性赋值。
PRIVATE，那么它实际是给 INCLUDE_DIRECTORIES这个属性赋值。
INTERFACE，那么它实际是给INTERFACE_INCLUDE_DIRECTORIES这个属性赋值。
PUBLIC，那么同时给INCLUDE_DIRECTORIES和INTERFACE_INCLUDE_DIRECTORIES赋值。

目标A本身编译生成时，找的是自己里面的INCLUDE_DIRECTORIES这个路径。
目标B生成需要链接目标A，那么它既找自己里面的INCLUDE_DIRECTORIES路径，也找目标A的INTERFACE_INCLUDE_DIRECTORIES路径。
]]

#学习来源：https://zhuanlan.zhihu.com/p/655302131